// 微服务性能测试用例
import { microservicesE2EConfig } from '../support/microservices-e2e-config.js'
import { testDataManager } from '../support/test-data-manager.js'

describe('微服务性能测试', () => {
  let performanceResults = []
  let testUsers = []
  let testCourses = []

  before(() => {
    // 准备测试数据
    cy.log('准备性能测试数据...')
  })

  after(() => {
    // 生成性能测试报告
    cy.log('性能测试结果:', performanceResults)
    
    // 清理测试数据
    testDataManager.cleanupTestData()
  })

  describe('API网关性能测试', () => {
    it('应该测试API网关的并发处理能力', () => {
      const concurrentRequests = 10
      const requestPromises = []
      
      // 创建并发请求
      for (let i = 0; i < concurrentRequests; i++) {
        const promise = cy.request({
          method: 'GET',
          url: `${microservicesE2EConfig.healthChecks.apiGateway.url.replace('/actuator/health', '')}/api/courses`,
          failOnStatusCode: false
        }).then((response) => {
          return {
            requestId: i,
            status: response.status,
            responseTime: response.duration,
            success: response.status < 500
          }
        })
        
        requestPromises.push(promise)
      }
      
      // 等待所有请求完成
      cy.wrap(Promise.all(requestPromises)).then((results) => {
        const successCount = results.filter(r => r.success).length
        const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
        
        expect(successCount, '大部分并发请求应该成功').to.be.greaterThan(concurrentRequests * 0.8)
        expect(avgResponseTime, '平均响应时间应该在合理范围内').to.be.lessThan(5000)
        
        performanceResults.push({
          testName: 'API网关并发测试',
          concurrentRequests,
          successCount,
          avgResponseTime,
          success: successCount >= concurrentRequests * 0.8
        })
      })
    })

    it('应该测试API网关的负载处理能力', () => {
      const totalRequests = 50
      const batchSize = 5
      const results = []
      
      // 分批发送请求
      const sendBatch = (batchIndex) => {
        const batchPromises = []
        
        for (let i = 0; i < batchSize; i++) {
          const requestIndex = batchIndex * batchSize + i
          if (requestIndex >= totalRequests) break
          
          const promise = cy.request({
            method: 'POST',
            url: `${microservicesE2EConfig.healthChecks.apiGateway.url.replace('/actuator/health', '')}/api/users/login`,
            body: {
              account: `loadtest_user_${requestIndex}`,
              password: 'Test@123'
            },
            failOnStatusCode: false
          }).then((response) => {
            return {
              requestId: requestIndex,
              status: response.status,
              responseTime: response.duration,
              success: response.status < 500
            }
          })
          
          batchPromises.push(promise)
        }
        
        return cy.wrap(Promise.all(batchPromises))
      }
      
      // 执行分批测试
      const executeLoadTest = () => {
        const batches = Math.ceil(totalRequests / batchSize)
        let currentBatch = 0
        
        const executeNextBatch = () => {
          if (currentBatch >= batches) {
            // 所有批次完成，分析结果
            const successCount = results.filter(r => r.success).length
            const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
            
            expect(successCount, '负载测试中大部分请求应该成功').to.be.greaterThan(totalRequests * 0.7)
            expect(avgResponseTime, '负载测试平均响应时间应该在合理范围内').to.be.lessThan(8000)
            
            performanceResults.push({
              testName: 'API网关负载测试',
              totalRequests,
              successCount,
              avgResponseTime,
              success: successCount >= totalRequests * 0.7
            })
            
            return
          }
          
          sendBatch(currentBatch).then((batchResults) => {
            results.push(...batchResults)
            currentBatch++
            executeNextBatch()
          })
        }
        
        executeNextBatch()
      }
      
      executeLoadTest()
    })
  })

  describe('微服务响应时间测试', () => {
    it('应该测试各个微服务的响应时间', () => {
      const services = [
        { name: 'userService', url: microservicesE2EConfig.healthChecks.userService.url.replace('/actuator/health', '/api/users') },
        { name: 'courseService', url: microservicesE2EConfig.healthChecks.courseService.url.replace('/actuator/health', '/api/courses') },
        { name: 'exerciseService', url: microservicesE2EConfig.healthChecks.exerciseService.url.replace('/actuator/health', '/api/exercises') },
        { name: 'progressService', url: microservicesE2EConfig.healthChecks.progressService.url.replace('/actuator/health', '/api/progress') }
      ]
      
      const serviceResults = []
      
      services.forEach(service => {
        cy.request({
          method: 'GET',
          url: service.url,
          failOnStatusCode: false
        }).then((response) => {
          serviceResults.push({
            service: service.name,
            status: response.status,
            responseTime: response.duration,
            success: response.status < 500
          })
        })
      })
      
      cy.wrap(serviceResults).then((results) => {
        results.forEach(result => {
          expect(result.responseTime, `${result.service} 响应时间应该在合理范围内`).to.be.lessThan(3000)
        })
        
        const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
        
        performanceResults.push({
          testName: '微服务响应时间测试',
          serviceResults: results,
          avgResponseTime,
          success: results.every(r => r.success && r.responseTime < 3000)
        })
      })
    })
  })

  describe('数据库性能测试', () => {
    it('应该测试数据库连接和查询性能', () => {
      // 测试数据库连接
      cy.request({
        method: 'GET',
        url: `${microservicesE2EConfig.healthChecks.mysql.url}/health`,
        failOnStatusCode: false
      }).then((response) => {
        expect(response.status, '数据库应该可访问').to.be.oneOf([200, 404]) // 404表示健康检查端点不存在，但服务可访问
        
        // 通过API测试数据库性能
        const dbTestPromises = []
        
        // 创建多个用户测试数据库写入性能
        for (let i = 0; i < 5; i++) {
          const promise = testDataManager.createTestUser({
            account: `perf_user_${Date.now()}_${i}`,
            name: `性能测试用户_${i}`
          }).then((result) => {
            return {
              operation: 'createUser',
              success: result.success,
              responseTime: result.responseTime || 0
            }
          })
          
          dbTestPromises.push(promise)
        }
        
        // 查询用户列表测试数据库读取性能
        const queryPromise = cy.request({
          method: 'GET',
          url: `${microservicesE2EConfig.healthChecks.apiGateway.url.replace('/actuator/health', '')}/api/users`,
          failOnStatusCode: false
        }).then((response) => {
          return {
            operation: 'queryUsers',
            success: response.status < 500,
            responseTime: response.duration
          }
        })
        
        dbTestPromises.push(queryPromise)
        
        cy.wrap(Promise.all(dbTestPromises)).then((results) => {
          const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
          const successCount = results.filter(r => r.success).length
          
          expect(successCount, '大部分数据库操作应该成功').to.be.greaterThan(results.length * 0.8)
          expect(avgResponseTime, '数据库操作平均响应时间应该在合理范围内').to.be.lessThan(2000)
          
          performanceResults.push({
            testName: '数据库性能测试',
            operations: results,
            avgResponseTime,
            success: successCount >= results.length * 0.8
          })
        })
      })
    })
  })

  describe('服务间通信性能测试', () => {
    it('应该测试微服务间通信的性能', () => {
      // 测试跨服务调用的性能
      const communicationTests = []
      
      // 测试用户创建后立即查询（涉及用户服务）
      const userTest = testDataManager.createTestUser({
        account: `comm_user_${Date.now()}`,
        name: '通信测试用户'
      }).then((userResult) => {
        if (userResult.success) {
          return cy.request({
            method: 'GET',
            url: `${microservicesE2EConfig.healthChecks.apiGateway.url.replace('/actuator/health', '')}/api/users/${userResult.user.id}`,
            failOnStatusCode: false
          }).then((response) => {
            return {
              test: '用户服务通信',
              success: response.status < 500,
              responseTime: response.duration
            }
          })
        }
        return { test: '用户服务通信', success: false, responseTime: 0 }
      })
      
      communicationTests.push(userTest)
      
      // 测试课程创建后立即查询（涉及课程服务）
      const courseTest = testDataManager.createTestCourse({
        courseName: `通信测试课程_${Date.now()}`,
        description: '测试微服务通信性能'
      }).then((courseResult) => {
        if (courseResult.success) {
          return cy.request({
            method: 'GET',
            url: `${microservicesE2EConfig.healthChecks.apiGateway.url.replace('/actuator/health', '')}/api/courses/${courseResult.course.courseId}`,
            failOnStatusCode: false
          }).then((response) => {
            return {
              test: '课程服务通信',
              success: response.status < 500,
              responseTime: response.duration
            }
          })
        }
        return { test: '课程服务通信', success: false, responseTime: 0 }
      })
      
      communicationTests.push(courseTest)
      
      cy.wrap(Promise.all(communicationTests)).then((results) => {
        const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
        const successCount = results.filter(r => r.success).length
        
        expect(successCount, '大部分服务间通信应该成功').to.be.greaterThan(results.length * 0.8)
        expect(avgResponseTime, '服务间通信平均响应时间应该在合理范围内').to.be.lessThan(4000)
        
        performanceResults.push({
          testName: '服务间通信性能测试',
          communicationResults: results,
          avgResponseTime,
          success: successCount >= results.length * 0.8
        })
      })
    })
  })

  describe('内存和资源使用测试', () => {
    it('应该监控服务的内存和资源使用情况', () => {
      // 通过健康检查端点获取服务状态信息
      const serviceHealthChecks = []
      
      Object.entries(microservicesE2EConfig.healthChecks).forEach(([serviceName, config]) => {
        if (serviceName !== 'mysql') { // 跳过数据库，只检查微服务
          const healthCheck = cy.request({
            method: 'GET',
            url: config.url,
            failOnStatusCode: false
          }).then((response) => {
            return {
              service: serviceName,
              status: response.status,
              healthy: response.status === 200,
              responseTime: response.duration
            }
          })
          
          serviceHealthChecks.push(healthCheck)
        }
      })
      
      cy.wrap(Promise.all(serviceHealthChecks)).then((results) => {
        const healthyServices = results.filter(r => r.healthy).length
        const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
        
        expect(healthyServices, '所有微服务应该健康运行').to.equal(results.length)
        expect(avgResponseTime, '健康检查平均响应时间应该在合理范围内').to.be.lessThan(2000)
        
        performanceResults.push({
          testName: '服务资源监控测试',
          serviceHealth: results,
          healthyServices,
          avgResponseTime,
          success: healthyServices === results.length
        })
      })
    })
  })

  describe('压力测试', () => {
    it('应该在压力条件下测试系统性能', () => {
      const stressTestConfig = microservicesE2EConfig.performance.stressTest
      const results = []
      
      // 模拟压力测试：快速连续创建和查询数据
      const stressOperations = []
      
      for (let i = 0; i < stressTestConfig.concurrentUsers; i++) {
        const operation = (() => {
          const userIndex = i
          return testDataManager.createTestUser({
            account: `stress_user_${Date.now()}_${userIndex}`,
            name: `压力测试用户_${userIndex}`
          }).then((userResult) => {
            if (userResult.success) {
              // 立即进行查询操作
              return cy.request({
                method: 'GET',
                url: `${microservicesE2EConfig.healthChecks.apiGateway.url.replace('/actuator/health', '')}/api/users`,
                failOnStatusCode: false
              }).then((response) => {
                return {
                  userIndex,
                  userCreated: userResult.success,
                  querySuccess: response.status < 500,
                  responseTime: response.duration
                }
              })
            }
            return {
              userIndex,
              userCreated: false,
              querySuccess: false,
              responseTime: 0
            }
          })
        })()
        
        stressOperations.push(operation)
      }
      
      cy.wrap(Promise.all(stressOperations)).then((results) => {
        const successfulOperations = results.filter(r => r.userCreated && r.querySuccess).length
        const avgResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0) / results.length
        
        // 压力测试的期望值相对较低
        expect(successfulOperations, '压力测试中大部分操作应该成功').to.be.greaterThan(results.length * 0.6)
        expect(avgResponseTime, '压力测试平均响应时间应该在可接受范围内').to.be.lessThan(10000)
        
        performanceResults.push({
          testName: '系统压力测试',
          totalOperations: results.length,
          successfulOperations,
          avgResponseTime,
          success: successfulOperations >= results.length * 0.6
        })
      })
    })
  })
})
